package kits.my;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;

import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.util.ImageHelper;

public class CaptchaKits {
	/**验证码破解*/
	public static String crack(File pic) {
		ITesseract instance = new Tesseract(); // JNA Interface Mapping
		// ITesseract instance = new Tesseract1(); // JNA Direct Mapping
		BufferedImage bin;
		String result = "";
		try {
			bin = ImageIO.read(pic);
			
			bin = process(bin);
			bin = removeLine(bin,10);
			result = instance.doOCR(bin);
		} catch (IOException | TesseractException e1) {
			e1.printStackTrace();
		}
		return result.trim();
	}

	private static BufferedImage process(BufferedImage bin) {
		int endX = bin.getWidth();
		int endY = bin.getHeight();
		// 这里对图片黑白处理,增强识别率.这里先通过截图,截取图片中需要识别的部分
		BufferedImage textImage = ImageHelper.convertImageToGrayscale(ImageHelper.getSubImage(bin, 0, 0, endX, endY));
		// 图片锐化,自己使用中影响识别率的主要因素是针式打印机字迹不连贯,所以锐化反而降低识别率
		// textImage = ImageHelper.convertImageToBinary(textImage);
		// 图片放大5倍,增强识别率(很多图片本身无法识别,放大5倍时就可以轻易识,但是考滤到客户电脑配置低,针式打印机打印不连贯的问题,这里就放大5倍)
		textImage = ImageHelper.getScaledInstance(textImage, endX * 5, endY * 5);
		AsFile(textImage);
		return textImage;
	}
	
	private static BufferedImage removeLine(BufferedImage img, int px) {
        if (img != null) {
            int width = img.getWidth();
            int height = img.getHeight();

            for (int x = 0; x < width; x++) {
                List<Integer> list = new ArrayList<Integer>();
                for (int y = 0; y < height; y++) {
                    int count = 0;
                    while (y < height - 1 ) {//&& img.getRGB(x, y)
                        count++;
                        y++;
                    }
                    if (count <= px && count > 0) {
                        for (int i = 0; i <= count; i++) {
                            list.add(y - i);
                        }
                    }
                }
                if (list.size() != 0) {
                    for (int i = 0; i < list.size(); i++) {
                        img.setRGB(x, list.get(i), Color.white.getRGB());
                    }
                }
            }
        }
        return img;

    }

	private static void AsFile(BufferedImage textImage) {
		File gifFile = new File("D:\\captcha\\" + System.currentTimeMillis() + ".gif");
		OutputStream out = null;
		try {
			out = new FileOutputStream(gifFile);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		try {
			ImageIO.write(textImage, "gif", out);
		} catch (IOException e) {
			e.printStackTrace();
		}
		IOUtils.closeQuietly(out);
	}
	
	public static void main(String[] args) {
		System.out.println(CaptchaKits.crack(new File("C:\\vcode.jpg")));
	}
}
